﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ext.Net;
using System.Web.UI.HtmlControls;
using System.Web.UI;
using System.Configuration;
using System.Web.Security;
using Sio.Mdm.Types.Settings;
using Sio.Mdm.Entities;

namespace Sio.Mdm.Web.Controls
{   
    public class Page : System.Web.UI.Page
    {
        #region Fields

        #endregion

        #region Construction
        public Page()
        {
            EnableTheming = true;
        }
        #endregion

        #region Properties

        #region Private
        #region _DefaultGridPageSize
        private static int _DefaultGridPageSize = 20;
        #endregion
        #endregion

        #region Protected

        #region UserSession
        /// <summary>
        /// Get current user session for authorization when calling BL functions
        /// </summary>
        protected Sio.Mdm.Types.Session UserSession
        {
            get
            {
                if (Session["__session"] != null)
                {
                    return Session["__session"] as Sio.Mdm.Types.Session;
                }

                //return Sio.Mdm.Types.Session.Current;
                return null;
            }
        }
        #endregion

        #region CurrentTheme
        private Ext.Net.Theme? _theme;
        protected virtual Ext.Net.Theme CurrentTheme
        {
            get
            {
                if (_theme == null)
                {
                    string theme = ConfigurationManager.AppSettings["Theme"];

                    try
                    {
                        if (theme != null)
                        {
                            Ext.Net.Theme cooliteTheme =
                                (Ext.Net.Theme)Enum.Parse(typeof(Ext.Net.Theme), theme);
                            _theme = cooliteTheme;
                        }
                        else
                        {
                            _theme = Ext.Net.Theme.Slate;
                        }
                    }
                    catch (Exception)
                    {
                        _theme = Ext.Net.Theme.Gray;
                    }
                }

                return _theme.Value;
            }
            set
            {
                Session["_theme"] = value;
            }
        }
        #endregion

        #region ScriptManager
        private Ext.Net.ResourceManager _sc;
        internal protected Ext.Net.ResourceManager ScriptManager
        {
            get
            {
                if (_sc == null)
                {
                    _sc = FindScriptManager();

                    if (_sc == null)
                    {
                        _sc = new Ext.Net.ResourceManager();
                        _sc.ID = "ScriptManager" + Guid.NewGuid();

                        HtmlForm form = Form == null ? FindForm() : Form;

                        // In cas some lame programer has failed to comply with rules
                        if (form == null)
                        {
                            Controls.AddAt(0, _sc);
                        }
                        else
                        {
                            form.Controls.AddAt(0, _sc);
                        }
                    }
                }

                //_sc.AjaxViewStateMode = ViewStateMode.Enabled;
                
                return _sc;
            }
        }
        #endregion

        #region DefaultGridPageSize
        internal protected int DefaultGridPageSize
        {
            get
            {
                return _DefaultGridPageSize;
            }
        }
        #endregion

        #region UserSettings
        private UserSettings _userSettings;
        /// <summary>
        /// Get user settings
        /// </summary>
        protected UserSettings UserSettings
        {
            get
            {
                if (null == _userSettings)
                {
                    _userSettings = EntityFactory.CreateInstance<UserSettings>();
                }

                return _userSettings;
            }
        } 
        #endregion

        #region SecurityTokenWriteEnabled
        /// <summary>
        /// Get wheater writing of security tokens is enabled. This should be turned 
        /// off when running final version. It can also be turned off in web.config.
        /// Just set "SecurityTokenEnableWrite" key to false.
        /// </summary>
        protected bool SecurityTokenWriteEnabled
        {
            get
            {
                string value = ConfigurationManager.AppSettings["SecurityTokenEnableWrite"];
                bool result = false;

                if (!String.IsNullOrEmpty(value))
                {
                    result = value.ToLower() == "true";
                }

                return result;
            }
        } 
        #endregion

        #endregion

        #region Private

        #region CurrentAspTheme
        private string CurrentAspTheme
        {
            get
            {
                return CurrentTheme.ToString();
            }
        }
        #endregion

        #region LocaleScript
        private string LocaleScript
        {
            get
            {
                string template = "~/script/locale/ext-lang-{0}.js";
                return String.Format(template, "en");
            }
        }
        #endregion

        #endregion

        #endregion

        #region Methods

        #region Public
        [DirectMethod]
        public string ButtonPressed(string id)
        {
            //DialogButtonType type = (DialogButtonType) Enum.Parse(typeof(DialogButtonType), id);
            //DialogButtonEventArgs args = new DialogButtonEventArgs(type);

            //OnDialogButton(args);
            
            //return JSON.Serialize(args); // args.Success;
            return String.Empty;
        }
        [DirectMethod]
				public bool OpenTab(string tabPanelId, string url, string title, int count, string tabId)
        {
            TabPanel panel = FindControl(tabPanelId) as TabPanel;

            if (panel == null)
            {
                return false;
            }
                        
            Panel tab = new Panel();

            tab.AutoLoad.ShowMask = true;
            tab.AutoLoad.Mode = LoadMode.IFrame;
            tab.AutoLoad.Url = url;
            tab.LazyMode = LazyMode.Instance;
            tab.AutoLoad.ShowMask = true;
            tab.Closable = true;
            tab.AutoLoad.TriggerEvent = "activate";
            
            tab.Border = false;
            tab.Title = title;
						if (!String.IsNullOrEmpty(tabId))
							tab.ID = tabId;
						else
							tab.ID = String.Format("{0}_{1}", tabPanelId, count);

            tab.Render(panel, RenderMode.AddTo);
            panel.SetActiveTab(tab.ID);

            return true;
        }
        #endregion

        #region Protected

        #region OnPreInit
        protected override void OnPreInit(EventArgs e)
        {
            if (!ExtNet.IsAjaxRequest)
            {
                Theme = CurrentAspTheme;
                //ScriptManager.RegisterClientStyleInclude("style", "~/script/CustomStyle.css");
                ScriptManager.RegisterClientScriptInclude(
                    "common",
                    ScriptManager.GetWebResourceUrl(
                        typeof(Page),
                        "Sio.Mdm.Web.Controls.scripts.common.js")
                );

                ScriptManager.CleanResourceUrl = false;
#if DEBUG
                //ScriptManager.ScriptMode = ScriptMode.Debug;
#endif
                //    "~/scripts/common.js");
                //ScriptManager.RegisterClientScriptInclude("locale", LocaleScript);
                //ScriptManager.RegisterClientScriptInclude("triggercombo", "~/script/TriggerCombo.js");
                //ScriptManager.RegisterClientScriptInclude("fileuploadfield", "~/script/FileUploadField.js");
            }

            if (Login.FirstLogin)
            {
                Login.FirstLogin = false;
                Login.DefaultUrl = Request.Path;
            }

            base.OnPreInit(e);
        }
        #endregion

        #region OnLoad
        protected override void OnLoad(EventArgs e)
        {
            // Set timeout in direct events to some reasonable time for debugging
            Ext.Net.ExtNet.Js.Set("Ext.net.DirectEvent.timeout", 180000);

            if (!ExtNet.IsAjaxRequest)
            {
                if (ScriptManager != null)
                {
                    ScriptManager.Theme = CurrentTheme;
                    ScriptManager.Locale = "sl-si";
                }
                
                SetGridPageSize(null);
                RegisterIcon(Icon.Accept);
                RegisterIcon(Icon.Cancel);
                RegisterIcon(Icon.Stop);
                RegisterIcon(Icon.StopRed);
                RegisterIcon(Icon.Disk);
                RegisterIcon(Icon.Decline);
                RegisterIcon(Icon.ArrowRight);
            }

            if (!Request.IsAuthenticated && GetType().Name != "login_aspx")
            {
                ExtNet.Redirect(FormsAuthentication.LoginUrl);
            }

            base.OnLoad(e);
        }
        protected override void EnsureChildControls()
        {
            base.EnsureChildControls();
        }        
        #endregion

        #region LoadUrlToContent
        /// <summary>
        /// Load specified URL to content panel of main page
        /// </summary>
        /// <param name="url">Url to navigate to</param>
        protected void LoadUrlToContent(string url)
        {
            ScriptManager.AddAfterClientInitScript(String.Format("navigateToUrl('{0}');", url));
        }
        #endregion

        #region RegisterStartupScript
        protected void RegisterStartupScript(string template, params object[] args)
        {
            //ClientScript.RegisterStartupScript
            //    (
            //    typeof(Base.Page),
            //    String.Empty,
            //    String.Format(UserControl.ScriptBlockTemplate, String.Format(template, args))
            //    );
        }
        #endregion

        #region RegisterIcon
        protected void RegisterIcon(Icon icon)
        {
            string iconKey = String.Format("icon:{0}", icon);

            if (Session[iconKey] != null)
            {
                return;
            }

            ScriptManager.AddScript("Ext.util.CSS.createStyleSheet({0}, {1});",
                    JSON.Serialize(ScriptManager.GetIconClass(icon)),
                    JSON.Serialize(Ext.Net.ResourceManager.GetIconClassName(icon)));
            Session[iconKey] = true;
        }
        #endregion

        #region OnDialogButton
        protected virtual void OnDialogButton(DialogButtonEventArgs e)
        {
            if (DialogButton != null)
            {
                DialogButton(this, e);
            }
        }
        #endregion

        #region getInputInteger
        public int getInputInteger(string theVar)
        {
            try
            {
                if (Request.QueryString[theVar] != null)
                {
                    string theValue = Request.QueryString[theVar];
                    Int32 izhod = Convert.ToInt32(theValue);
                    return izhod;
                }
                else return -1;
            }
            catch
            {
                return -1;
            }
        }
        #endregion 
        
        #region getInputString
        public string getInputString(string theVar)
        {
            if (Request.QueryString[theVar] != null)
                return Request.QueryString[theVar];
            else
                return "";
        }
        #endregion

        #region IsDbNull
        public static bool IsDBNull(object Expression)
        {
            if (Expression == null)
                return false;
            return (Expression is DBNull);
        }
        #endregion

        #region OnPreRender
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            
            if (SecurityTokenWriteEnabled && !ExtNet.IsAjaxRequest)
            {
                WriteSecurityTokens(null, null);
            }
        } 
        #endregion

        #region ShowExt* (Client notifications support)        
        protected void ShowExtMessageBox(string title, string htmlMessage)
        {            
            ShowExtMessageBox(title, htmlMessage, MessageBox.Icon.INFO);
        }

        protected void ShowExtMessageBox(string title, string htmlMessage, MessageBox.Icon icon)
        {
            X.Msg.Show(new MessageBoxConfig
            {
                Title = title,
                Icon = icon,
                Message = htmlMessage,
                Buttons = MessageBox.Button.OK
            });
        }

        protected void ShowExtNotification(string title, string htmlMessage)
        {
            Ext.Net.Icon icon = Icon.Information;

            Notification.Show(new NotificationConfig
            {
                Title = title,
                Icon = icon,
                Html = htmlMessage,
                HideDelay = 4000,
                Width = 200
            });
        }
        #endregion

        #endregion

        #region Private

        #region FindScriptManager
        private HtmlForm FindForm()
        {
            return FindControl(null, typeof(HtmlForm)) as HtmlForm;
        }
        private Ext.Net.ResourceManager FindScriptManager()
        {
            return FindControl(null, typeof(Ext.Net.ResourceManager)) as Ext.Net.ResourceManager;
        }
        private Control FindControl(Control parent, Type type)
        {
            ControlCollection controls = parent == null ? Controls : parent.Controls;

            foreach (Control ctrl in controls)
            {
                if (ctrl.GetType() == type)
                {
                    return ctrl;
                }

                Control sc = FindControl(ctrl, type);

                if (sc != null)
                {
                    return sc;
                }
            }

            return null;
        }
        #endregion

        #region SetGridPageSize
        private void SetGridPageSize(Control parent)
        {
            ControlCollection controls = parent == null ? Controls : parent.Controls;

            foreach (Control ctrl in controls)
            {
                if (ctrl is Ext.Net.Store)
                {
                    Ext.Net.Store store = ctrl as Ext.Net.Store;
                    Ext.Net.Parameter parameter = new Ext.Net.Parameter("limit", "30");
                    if (store.BaseParams["limit"] != null)
                    {
                        store.BaseParams["limit"] = DefaultGridPageSize.ToString();
                    }
                }

                if (ctrl is Ext.Net.PagingToolbar)
                {
                    Ext.Net.PagingToolbar pagingtoolbar = ctrl as Ext.Net.PagingToolbar;
                    pagingtoolbar.PageSize = DefaultGridPageSize;
                }

                SetGridPageSize(ctrl);                
            }
        }

        #endregion

        #region WriteSecurityTokens
        private void WriteSecurityTokens(Control control, string root)
        {
            control = control ?? this;
            root = root ?? GetType().Name;

            // TODO: Move security token writer to utils
            Security.SecurityTokenCache.AddToken(root);

            foreach (Control ctrl in control.Controls)
            {
                if (String.IsNullOrEmpty(ctrl.ID))
                {
                    continue;
                }

                WriteSecurityTokens(ctrl, String.Format("{0}.{1}", root, ctrl.ID));
            }
        }
        #endregion

        #endregion

        #endregion

        #region Events
        public event EventHandler<DialogButtonEventArgs> DialogButton;
        #endregion
    }

    
}
